package com.yqs.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.Reader;

/**
 * MyBatis 工具类，用于创建和获取 SqlSessionFactory 和 SqlSession。
 *
 * @author Ye QS
 * @version 0.1
 * @className SqlSessionFactoryUtil
 * @description 此类封装了 MyBatis 的配置和会话管理，确保 SqlSessionFactory 是单例的，并且可以被整个应用程序共享。
 * @date 2024/7/29 11:33
 * @since jdk11
 */
public class SqlSessionFactoryUtil {
    // 定义 SqlSessionFactory 的静态实例，确保它是单例的。
    private static SqlSessionFactory factory;

    /**
     * 私有构造函数，防止此类被实例化。
     */
    private SqlSessionFactoryUtil() {
    }

    /**
     * 静态初始化块，用于初始化 SqlSessionFactory。
     * 从类路径下的 mybatis.xml 配置文件中读取 MyBatis 配置，并创建 SqlSessionFactory。
     */
    static {
        try {
            // 使用 Resources 类加载 mybatis 配置文件。
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            // 创建 SqlSessionFactoryBuilder 实例。
            SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
            // 使用配置文件构建 SqlSessionFactory。
            factory = factoryBuilder.build(reader);
        } catch (IOException e) {
            // 如果在读取配置文件或创建 SqlSessionFactory 时发生异常，抛出运行时异常。
            throw new RuntimeException("Error initializing SqlSessionFactory", e);
        }
    }

    /**
     * 获取 SqlSession 的方法。
     * 此方法将返回一个新的 SqlSession 实例，并且自动提交事务。
     *
     * @return 返回一个新的 SqlSession 实例。
     */
    public static SqlSession getSqlSession() {
        // 调用 factory 的 openSession 方法，并传入 true 参数以自动提交事务。
        return factory.openSession(true);
    }
}